#!/bin/bash

set -e

cd /source
VERSION=$1

OLD_VERSION=`cat VERSION`
OLD_MAJOR=$(echo $OLD_VERSION | cut -d. -f1)
OLD_MINOR=$(echo $OLD_VERSION | cut -d. -f2)
OLD_PATCH=$(echo $OLD_VERSION | cut -d. -f3)
NEW_MAJOR=$(echo $VERSION | cut -d. -f1)
NEW_MINOR=$(echo $VERSION | cut -d. -f2)
NEW_PATCH=$(echo $VERSION | cut -d. -f3)
USER_EMAIL=$(git config --get user.email || echo "noemail@set.any.where")
USER_NAME=$(git config --get user.name || echo "unknown user")
VERSION_FILE_LIST="README.md doc/man/*.xml
	scl/syslog-ng.conf
	docker/syslog-ng.conf
	contrib/openbsd-packaging/syslog-ng.conf
	packaging/debian/syslog-ng.conf
	packaging/rhel/syslog-ng.conf"

function update_version() {
	echo Updating VERSION file
	echo $VERSION > VERSION
}

function update_packaging_debian() {
	echo Updating Debian packaging
	DEBFULLNAME=$USER_NAME DEBEMAIL=$USER_EMAIL debchange --distribution unstable --newversion "$VERSION-1" -c packaging/debian/changelog "New upstream release $VERSION"
}

function update_packaging_rhel() {
	echo Updating RHEL packaging
	sed -i -e "s/^Version: [0-9.]*$/Version: $VERSION/g" packaging/rhel/syslog-ng.spec
	sed -i -e "/^%changelog/ a * `date '+%a %b %e %Y'` $USER_NAME <$USER_EMAIL> - $VERSION-1\n- updated to $VERSION\n" packaging/rhel/syslog-ng.spec
}

function update_version_refs_in_source() {
	echo Updating version references in source files
	ESCAPED_OLD_MAJOR_AND_MINOR=$(echo $OLD_MAJOR.$OLD_MINOR | sed -e 's/[]\/$*.^[]/\\&/g') &&
	ESCAPED_NEW_MAJOR_AND_MINOR=$(echo $NEW_MAJOR.$NEW_MINOR | sed -e 's/[\/&]/\\&/g') &&
	git ls-files $VERSION_FILE_LIST | xargs sed -i "s/$ESCAPED_OLD_MAJOR_AND_MINOR/$ESCAPED_NEW_MAJOR_AND_MINOR/g"
}

function update_versioning_h() {
	echo Updating versioning.h
	VERSIONING_H="lib/versioning.h"

	if grep -E "^#define VERSION_${NEW_MAJOR}_${NEW_MINOR} +\"syslog-ng ${NEW_MAJOR}.${NEW_MINOR}\"$" ${VERSIONING_H}; then
		echo "VERSION_${NEW_MAJOR}_${NEW_MINOR} is already defined."
	else
		sed -E -i "/^#define VERSION_${OLD_MAJOR}_${OLD_MINOR} +\"syslog-ng ${OLD_MAJOR}.${OLD_MINOR}\"$/a#define VERSION_${NEW_MAJOR}_${NEW_MINOR} \"syslog-ng ${NEW_MAJOR}.${NEW_MINOR}\"" ${VERSIONING_H}
	fi

	OLD_HEX=$(grep "#define VERSION_VALUE_${OLD_MAJOR}_${OLD_MINOR}" ${VERSIONING_H} | grep -o "0x.*$")
	NEW_HEX=$(printf "0x%04X" $((${NEW_MAJOR} * 256 + ${NEW_MINOR})) | tr "[:upper:]" "[:lower:]")

	if grep -E "^#define VERSION_VALUE_${NEW_MAJOR}_${NEW_MINOR} +${NEW_HEX}$" ${VERSIONING_H}; then
		echo "VERSION_VALUE_${NEW_MAJOR}_${NEW_MINOR} is already defined."
	else
		sed -E -i "/^#define VERSION_VALUE_${OLD_MAJOR}_${OLD_MINOR} +${OLD_HEX}$/a#define VERSION_VALUE_${NEW_MAJOR}_${NEW_MINOR} ${NEW_HEX}" ${VERSIONING_H}
	fi

	sed -E -i "s/^#define VERSION_VALUE_CURRENT +VERSION_VALUE_${OLD_MAJOR}_${OLD_MINOR}$/#define VERSION_VALUE_CURRENT   VERSION_VALUE_${NEW_MAJOR}_${NEW_MINOR}/g" ${VERSIONING_H}
	sed -E -i "s/^#define VERSION_STR_CURRENT +\"${OLD_MAJOR}.${OLD_MINOR}\"$/#define VERSION_STR_CURRENT     \"${NEW_MAJOR}.${NEW_MINOR}\"/g" ${VERSIONING_H}
	sed -E -i "s/^#define VERSION_PRODUCT_CURRENT +VERSION_${OLD_MAJOR}_${OLD_MINOR}$/#define VERSION_PRODUCT_CURRENT VERSION_${NEW_MAJOR}_${NEW_MINOR}/g" ${VERSIONING_H}
}

function perform_updates()
{
	update_version && \
		update_packaging_debian && \
		update_packaging_rhel && \
		update_version_refs_in_source && \
		update_versioning_h
}

if [ "$VERSION" = "" ]; then
	echo "Please supply version number as first argument"
	exit 1
fi

if ! git diff-index --quiet HEAD; then
	echo "This script only operates on a clean git tree and git is required"
	exit 1
fi

if perform_updates; then
	echo "The proposed version changes have been saved as local changes. Review and commit them or abort using 'git reset --hard'."
else
	echo "Updating the files have failed, falling back to the original state."
	git reset --hard
fi
